<template>
  <div class="lazy-cascader" :style="{ width: width }">
    <!-- 禁用状态 -->
    <div>
      {{ current }}
        <el-cascader
            :ref="`panelRef`"
            v-model="current"
            :options="filterOptions"
            :props="currentProps"
        ></el-cascader>
      </div>
    <div
        v-if="disabled"
        class="el-input__inner lazy-cascader-input lazy-cascader-input-disabled"
    >
      <span class="lazy-cascader-placeholder" v-show="placeholderVisible">
        {{ placeholder }}
      </span>
      <div class="lazy-cascader-tags" v-if="props.multiple">
        <el-tag
            class="lazy-cascader-tag"
            type="info"
            disable-transitions
            v-for="(item, index) in labelArray"
            :key="index"
            closable
        >
          <span> {{ item.label.join(separator) }}</span>
        </el-tag>
      </div>
      <div class="lazy-cascader-label" v-else>
        <el-tooltip
            placement="top-start"
            :content="labelObject.label.join(separator)"
        >
          <span>{{ labelObject.label.join(separator) }}</span>
        </el-tooltip>
      </div>
    </div>
    <!-- 禁用状态 -->
    <!-- 可选状态 -->
    <el-popover trigger="click" placement="bottom-start" ref="popover">
      <!-- 搜索 -->
      <div class="lazy-cascader-search">
        <el-input v-model="keyword"></el-input>
      </div>
      <!-- 搜索 -->
      <!-- 级联面板 -->
      <div class="lazy-cascader-panel">
        <el-cascader-panel
            :ref="`panelRef`"
            v-model="current"
            :options="filterOptions"
            :props="currentProps"
            @change="change"
        ></el-cascader-panel>
      </div>
      <!-- 级联面板 -->
      <!--内容区域-->

      <div
          class="el-input__inner lazy-cascader-input"
          :class="disabled ? 'lazy-cascader-input-disabled' : ''"
          slot="reference"
      >
        <span class="lazy-cascader-placeholder" v-show="placeholderVisible">
          {{ placeholder }}
        </span>
        <div class="lazy-cascader-tags" v-if="props.multiple">
          <el-tag
              class="lazy-cascader-tag"
              type="info"
              disable-transitions
              v-for="(item, index) in labelArray"
              :key="index"
              closable
              @close="handleClose(item)"
          >
            <span> {{ item.label.join(separator) }}</span>
          </el-tag>
        </div>
        <div class="lazy-cascader-label" v-else>
          <el-tooltip
              placement="top-start"
              :content="labelObject.label.join(separator)"
          >
            <span>{{
                (props.orderbyDesc ? [...labelObject.label].reverse() : labelObject.label).join(separator)
              }}</span>
          </el-tooltip>
        </div>
      </div>
      <!--内容区域-->
    </el-popover>
    <!-- 可选状态 -->
  </div>
</template>
<script>
  export default {
    props: {
      value: {
        type: Array,
        default: () => {
          return [];
        }
      },
      separator: {
        type: String,
        default: ' > '
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      width: {
        type: String,
        default: '100%'
      },
      filterable: Boolean,
      disabled: Boolean,
      props: {
        type: Object,
        default: () => {
          return {
            label:'label'
          };
        }
      },
      suggestionsPopperClass: {
        type: String,
        default: 'suggestions-popper-class'
      },
      searchWidth: {
        type: String
      },
      searchEmptyText: {
        type: String,
        default: '暂无数据'
      },
    },
    data() {
      return {
        singleHandleSelect: false, //用于解决插件延时bug
        isSearchEmpty: false,
        keyword: '',
        closeHandleSelect: 4000,
        options: [],
        current: [],
        labelObject: {label: [], value: []},
        labelArray: [],
        currentProps: {
          multiple: this.props.multiple,
          checkStrictly: this.props.checkStrictly,
          value: this.props.value||'value',
          label: this.props.label||'label',
          leaf: this.props.leaf,
          lazy: true,
          lazyLoad: this.lazyLoad
        },
        filterOptions:[]
      };
    },
    computed: {
      placeholderVisible() {
        if (this.current) {
          return this.current.length === 0;
        } else {
          return true;
        }
      }
    },
    watch: {
      async current() {
        await this.getLabelArray();
        // 异步完成，再通知change事件
        if(this.singleHandleSelect){
          this.change();
          this.singleHandleSelect = false;
        }
      },
      value(v) {
        console.log(6666,v)
        this.current = v;
      },
      keyword(val) {
        this.isSearchEmpty = false;
        this.filterOptions = this.options.filter(item=>{
          console.log(item.label.toUpperCase().indexOf(val.toUpperCase()))
        return item.label.toUpperCase().indexOf(val.toUpperCase())>-1
        })

        console.log(this.filterOptions,val)
      }
    },
    created() {
      this.initOptions();
    },
    methods: {
      //搜索是否选中
      isChecked(value) {
        //多选
        if (this.props.multiple) {
          let index = this.current.findIndex(item => {
            return item.join() === value.join();
          });
          if (index > -1) {
            return 'el-link el-link--primary';
          } else {
            return '';
          }
        } else {
          if (value.join() === this.current.join()) {
            return 'el-link el-link--primary';
          } else {
            return '';
          }
        }
      },
      //搜索
      querySearch(query, callback) {
        this.props.lazySearch(query, list => {
          // console.log('list', list);
          callback(list);
          if (!list || !list.length) this.isSearchEmpty = true;
        }, this.props.type);
      },
      //选中搜索下拉搜索项
      handleSelect(item) {
        if (this.props.multiple) {
          // console.log('multiple', item);
          let index = this.current.findIndex(obj => {
            return obj.join() === item[this.props.value].join();
          });
          if (index === -1) {
            this.$refs[`panel${this.props.type}`].clearCheckedNodes();
            this.current.push(item[this.props.value]);
            // setTimeout(() => {
              // this.change();
            // },  this.closeHandleSelect);
            this.singleHandleSelect = true;
          }
        } else {
          // console.log('single', item);
          //选中下拉选变更值
          // console.log(item,this.current);
          if (
              this.current == null ||
              item[this.props.value].join() !== this.current.join()
          ) {
            this.$refs[`panel${this.props.type}`].activePath = [];
            this.current = item[this.props.value];
            // setTimeout(() => {
              // this.change();
            // }, this.closeHandleSelect);
            this.singleHandleSelect = true;
          }
        }
        this.keyword = '';
      },
      //初始化数据
      async initOptions() {
        this.props.lazyLoad({level:0,path:''}, list => {
          this.$set(this, 'options', list);
          this.$set(this, 'filterOptions', list);
          if (this.props.multiple) {
            this.current = [...this.value];
          } else {
            this.current = this.value;
          }
        }, this.props.type);
      },
      async getLabelArray() {
        if (this.props.multiple) {
          let array = [];
          for (let i = 0; i < this.current.length; i++) {
            let obj = await this.getObject(this.current[i]);
            array.push(obj);
          }
          this.labelArray = array;
          this.$emit('input', this.current);
          if (!this.disabled) {
            this.$nextTick(() => {
              this.$refs.popover.updatePopper();
            });
          }
        } else {
          this.labelObject = await this.getObject(this.current || []);
          this.$emit('input', this.current);
        }
      },
      /**格式化id=>object */
      async getObject(id) {
        try {
          let options = this.options;
          let nameArray = [];
          for (let i = 0; i < id.length; i++) {
            let index = options.findIndex(item => {
              return item[this.props.value] === id[i];
            });
            nameArray.push(options[index][this.props.label]);
            if (i < id.length - 1 && options[index].children == undefined) {
              let list = new Promise(resolve => {
                this.props.lazyLoad(id[i], list => {
                  resolve(list);
                }, this.props.type);
              }, this.props.type);
              this.$set(options[index], 'children', await list);
              options = options[index].children;
            } else {
              options = options[index].children;
            }
          }
          return {value: id, label: nameArray};
        } catch (e) {
          this.current = [];
          return {value: [], label: []};
        }
      },
      //懒加载数据
      async lazyLoad(node, resolve) {
        console.log('lazyLoad');
        let current = this.current;
        if (this.props.multiple) {
          current = [...this.current];
        }
        if (node.root) {
          resolve();
        } else if (node.data[this.props.leaf]) {
          resolve();
        } else if (node.data.children) {
          if (this.props.multiple) {
            this.current = current;
          }
          resolve();
        } else {
          this.props.lazyLoad(node, list => {
            node.data.children = list;
            if (this.props.multiple) {
              this.current = current;
            }
            resolve(list);
          }, this.props.type);
        }
      },
      //删除多选值
      /**删除**/
      handleClose(item) {
        let index = this.current.findIndex(obj => {
          return obj.join() == item.value.join();
        });
        if (index > -1) {
          this.$refs[`panel${this.props.type}`].clearCheckedNodes();
          this.current.splice(index, 1);
          this.$emit('change', this.current);
        }
      },
      change() {
        this.$emit('change', this.current);
        this.$refs.popover.doClose();
      },
      getCheckedNodes(){
        return this.$refs.panelRef.getCheckedNodes()
      }
    }
  };
</script>
<style lang="less">
  .lazy-cascader {
    display: inline-block;
    width: 100%;

    .lazy-cascader-input {
      width: 100%;
      background: #fff;
      height: auto;
      min-height: 32px;
      line-height: 1;
      cursor: pointer;

      > .lazy-cascader-placeholder {
        padding: 0 2px;
        line-height: 28px;
        color: #a8abb2;
        font-size: 14px;
      }

      > .lazy-cascader-label {
        padding: 0 2px;
        line-height: 28px;
        color: #606266;
        font-size: 14px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }

    .lazy-cascader-input-disabled {
      background-color: #f5f7fa;
      border-color: #e4e7ed;
      color: #c0c4cc;
      cursor: not-allowed;

      > .lazy-cascader-label {
        color: #c0c4cc;
      }

      > .lazy-cascader-placeholder {
        color: #c0c4cc;
      }
    }
  }

  .lazy-cascader-tag {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    margin: 2px;
    text-overflow: ellipsis;
    background: #f0f2f5;

    > span {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    > .el-icon-close {
      -webkit-box-flex: 0;
      -ms-flex: none;
      flex: none;
      background-color: #c0c4cc;
      color: #fff;
    }
  }

  .lazy-cascader-panel {
    margin-top: 10px;
    display: inline-block;
  }

  .suggestions-popper-class {
    width: auto !important;
    min-width: 200px;
  }

  .lazy-cascader-search {
    .empty {
      width: calc(100% - 24px);
      box-sizing: border-box;
      background-color: #fff;
      color: #999;
      text-align: center;
      position: absolute;
      z-index: 999;
      padding: 12px 0;
      margin-top: 12px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

      &:before {
        content: "";
        position: absolute;
        top: -12px;
        left: 36px;
        width: 0;
        height: 0;
        border-left: 6px solid transparent;
        border-right: 6px solid transparent;
        border-top: 6px solid transparent;
        border-bottom: 6px solid #fff;
        filter: drop-shadow(0 -1px 2px rgba(0, 0, 0, .02));
      }
    }
  }
</style>
